import type { RouteRecordRaw } from 'vue-router';

import { useAppStore } from '@/store/modules/app';
import { useAuthStore } from '@/store/modules/auth';
import { useIdentityStore } from '@/store/modules/identity';

import { useTabs } from './useTabs';

import { router, resetRouter } from '@/router';
// import { RootRoute } from '@/router/routes';

import projectSetting from '@/settings/projectSetting';
import { AuthModeEnum } from '@/enums/appEnum';
import { RoleEnum } from '@/enums/roleEnum';

import { intersection } from 'lodash-es';
import { isArray } from '@/utils/is';
import { useMultipleTabStore } from '@/store/modules/multipleTab';

/** 授权函数 */
export function useAuth() {
  const identityStore = useIdentityStore();
  const appStore = useAppStore();
  const authStore = useAuthStore();
  const { closeAll } = useTabs(router);

  /** 更改授权模式 */
  async function toggleAuthMode() {
    appStore.setProjectConfig({
      authMode:
        appStore.projectConfig?.authMode === AuthModeEnum.BACK
          ? AuthModeEnum.ROUTE_MAPPING
          : AuthModeEnum.BACK,
    });
    location.reload();
  }

  /**
   * Reset and regain authority resource information
   * 重置和重新获得权限资源信息
   * @param clearTabs 清除已打开标签
   */
  async function resume(clearTabs: boolean = true) {
    if (clearTabs) {
      const tabStore = useMultipleTabStore();
      tabStore.clearCacheTabs();
    }
    const tabStore = useMultipleTabStore();
    tabStore.clearCacheTabs();
    resetRouter();

    // 动态加载路由（再次）
    const routes = await authStore.buildRoutesAction();
    routes.forEach((route) => {
      router.addRoute(route as unknown as RouteRecordRaw);
    });

    authStore.setLastBuildMenuTime();
    if (clearTabs) {
      closeAll();
    }
  }

  /** 是否拥有授权 */
  function hasAuth(value?: RoleEnum | RoleEnum[] | string | string[], def = true): boolean {
    // 默认拥有
    if (!value) {
      return def;
    }

    const authMode = appStore.getProjectConfig.authMode;

    if ([AuthModeEnum.ROUTE_MAPPING, AuthModeEnum.ROLE].includes(authMode)) {
      const allRoleList = identityStore.getRoleList || [];
      if (!isArray(value)) {
        return allRoleList.includes(value as string);
      }
      return (intersection(value, allRoleList) as string[]).length > 0;
    }

    if (AuthModeEnum.BACK === authMode) {
      const accessCodes = authStore.getAccessCodes;
      if (!isArray(value)) {
        const splits = ['||', '&&'];
        const splitName = splits.find((item) => value.includes(item));
        if (splitName) {
          const splitCodes = value.split(splitName);
          return splitName === splits[0]
            ? intersection(splitCodes, accessCodes).length > 0
            : intersection(splitCodes, accessCodes).length === splitCodes.length;
        }
        return accessCodes.includes(value);
      }
      return intersection(value, accessCodes).length > 0;
    }
    return true;
  }

  /** 更改角色 */
  async function changeRole(roles: string | string[]): Promise<void> {
    if (
      projectSetting.authMode !== AuthModeEnum.ROUTE_MAPPING &&
      projectSetting.authMode !== AuthModeEnum.ROLE
    ) {
      throw new Error(
        // 'Please switch AuthModeEnum to ROUTE_MAPPING mode in the configuration to operate!',
        '请在配置中将AuthModeEnum切换到角色或路由映射模式进行操作！',
      );
    }

    if (!isArray(roles)) {
      roles = [roles];
    }
    identityStore.setRoleList(roles);
    await resume();
  }

  /** 刷新菜单 */
  async function refreshMenu(clearTabs: boolean = true) {
    await resume(clearTabs);
  }

  return {
    /** 更改授权模式 */
    toggleAuthMode,
    /** 是否拥有授权 */
    hasAuth,
    /** 更改角色 */
    changeRole,
    /** 刷新菜单 */
    refreshMenu,
  };
}
